#include "tablet-unstable-v2-client-protocol.h"
#include <wayland/xdg-shell-unstable-v6-client-protocol.h>
#include <wayland/xdg-foreign-unstable-v1-client-protocol.h>
+#include <wayland/server-decoration-client-protocol.h>
/**
* SECTION:wayland_interaction
wl_shm_format
};
+static void
+server_decoration_manager_default_mode (void *data,
+ struct org_kde_kwin_server_decoration_manager *manager,
+ uint32_t mode)
+{
+ g_assert (mode <= ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER);
+ const char *modes[] = {
+ [ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_NONE] = "none",
+ [ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_CLIENT] = "client",
+ [ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER] = "server",
+ };
+ GdkWaylandDisplay *display_wayland = data;
+ g_debug ("Compositor prefers decoration mode '%s'", modes[mode]);
+ display_wayland->server_decoration_mode = mode;
+}
+
+static const struct org_kde_kwin_server_decoration_manager_listener server_decoration_listener = {
+ .default_mode = server_decoration_manager_default_mode
+};
+
+gboolean
+gdk_wayland_display_prefers_ssd (GdkDisplay *display)
+{
+ GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
+ if (display_wayland->server_decoration_manager)
+ return display_wayland->server_decoration_mode == ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER;
+ return FALSE;
+}
+
static void
gdk_registry_handle_global (void *data,
struct wl_registry *registry,
wl_registry_bind (display_wayland->wl_registry, id,
&zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1);
}
+ else if (strcmp (interface, "org_kde_kwin_server_decoration_manager") == 0)
+ {
+ display_wayland->server_decoration_manager =
+ wl_registry_bind (display_wayland->wl_registry, id,
+ &org_kde_kwin_server_decoration_manager_interface, 1);
+ org_kde_kwin_server_decoration_manager_add_listener (display_wayland->server_decoration_manager,
+ &server_decoration_listener,
+ display_wayland);
+ }
else
handled = FALSE;
#include <gdk/wayland/xdg-shell-unstable-v6-client-protocol.h>
#include <gdk/wayland/xdg-foreign-unstable-v1-client-protocol.h>
#include <gdk/wayland/keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h>
+#include <gdk/wayland/server-decoration-client-protocol.h>
#include <glib.h>
#include <gdk/gdkkeys.h>
struct zxdg_exporter_v1 *xdg_exporter;
struct zxdg_importer_v1 *xdg_importer;
struct zwp_keyboard_shortcuts_inhibit_manager_v1 *keyboard_shortcuts_inhibit;
+ struct org_kde_kwin_server_decoration_manager *server_decoration_manager;
GList *async_roundtrips;
int data_device_manager_version;
int gtk_shell_version;
+ uint32_t server_decoration_mode;
+
struct xkb_context *xkb_context;
GdkWaylandSelection *selection;
void gdk_wayland_display_set_startup_notification_id (GdkDisplay *display,
const char *startup_id);
+gboolean gdk_wayland_display_prefers_ssd (GdkDisplay *display);
+
G_END_DECLS
#endif /* __GDK_WAYLAND_DISPLAY_H__ */
gboolean gdk_wayland_window_set_transient_for_exported (GdkWindow *window,
char *parent_handle_str);
+void gdk_wayland_window_announce_csd (GdkWindow *window);
+
G_END_DECLS
#endif /* __GDK_WAYLAND_WINDOW_H__ */
struct wl_egl_window *egl_window;
struct wl_egl_window *dummy_egl_window;
struct zxdg_exported_v1 *xdg_exported;
+ struct org_kde_kwin_server_decoration *server_decoration;
} display_server;
EGLSurface egl_surface;
ZXDG_POSITIONER_V6_GRAVITY_RIGHT);
}
+void
+gdk_wayland_window_announce_csd (GdkWindow *window)
+{
+ GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
+ GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+ if (!display_wayland->server_decoration_manager)
+ return;
+ impl->display_server.server_decoration =
+ org_kde_kwin_server_decoration_manager_create (display_wayland->server_decoration_manager,
+ impl->display_server.wl_surface);
+ if (impl->display_server.server_decoration)
+ org_kde_kwin_server_decoration_request_mode (impl->display_server.server_decoration,
+ ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_CLIENT);
+}
+
static GdkWindow *
get_real_parent_and_translate (GdkWindow *window,
gint *x,
['xdg-shell', 'unstable', 'v6', ],
['xdg-foreign', 'unstable', 'v1', ],
['tablet', 'unstable', 'v2', ],
- [ 'keyboard-shortcuts-inhibit', 'unstable', 'v1', ],
+ ['keyboard-shortcuts-inhibit', 'unstable', 'v1', ],
+ ['server-decoration', 'stable' ],
]
gdk_wayland_gen_headers = []
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="server_decoration">
+ <copyright><![CDATA[
+ Copyright (C) 2015 Martin Gräßlin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 2.1 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ ]]></copyright>
+ <interface name="org_kde_kwin_server_decoration_manager" version="1">
+ <description summary="Server side window decoration manager">
+ This interface allows to coordinate whether the server should create
+ a server-side window decoration around a wl_surface representing a
+ shell surface (wl_shell_surface or similar). By announcing support
+ for this interface the server indicates that it supports server
+ side decorations.
+ </description>
+ <request name="create">
+ <description summary="Create a server-side decoration object for a given surface">
+ When a client creates a server-side decoration object it indicates
+ that it supports the protocol. The client is supposed to tell the
+ server whether it wants server-side decorations or will provide
+ client-side decorations.
+
+ If the client does not create a server-side decoration object for
+ a surface the server interprets this as lack of support for this
+ protocol and considers it as client-side decorated. Nevertheless a
+ client-side decorated surface should use this protocol to indicate
+ to the server that it does not want a server-side deco.
+ </description>
+ <arg name="id" type="new_id" interface="org_kde_kwin_server_decoration"/>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ </request>
+ <enum name="mode">
+ <description summary="Possible values to use in request_mode and the event mode."/>
+ <entry name="None" value="0" summary="Undecorated: The surface is not decorated at all, neither server nor client-side. An example is a popup surface which should not be decorated."/>
+ <entry name="Client" value="1" summary="Client-side decoration: The decoration is part of the surface and the client."/>
+ <entry name="Server" value="2" summary="Server-side decoration: The server embeds the surface into a decoration frame."/>
+ </enum>
+ <event name="default_mode">
+ <description summary="The default mode used on the server">
+ This event is emitted directly after binding the interface. It contains
+ the default mode for the decoration. When a new server decoration object
+ is created this new object will be in the default mode until the first
+ request_mode is requested.
+
+ The server may change the default mode at any time.
+ </description>
+ <arg name="mode" type="uint" summary="The default decoration mode applied to newly created server decorations."/>
+ </event>
+ </interface>
+ <interface name="org_kde_kwin_server_decoration" version="1">
+ <request name="release" type="destructor">
+ <description summary="release the server decoration object"/>
+ </request>
+ <enum name="mode">
+ <description summary="Possible values to use in request_mode and the event mode."/>
+ <entry name="None" value="0" summary="Undecorated: The surface is not decorated at all, neither server nor client-side. An example is a popup surface which should not be decorated."/>
+ <entry name="Client" value="1" summary="Client-side decoration: The decoration is part of the surface and the client."/>
+ <entry name="Server" value="2" summary="Server-side decoration: The server embeds the surface into a decoration frame."/>
+ </enum>
+ <request name="request_mode">
+ <description summary="The decoration mode the surface wants to use."/>
+ <arg name="mode" type="uint" summary="The mode this surface wants to use."/>
+ </request>
+ <event name="mode">
+ <description summary="The new decoration mode applied by the server">
+ This event is emitted directly after the decoration is created and
+ represents the base decoration policy by the server. E.g. a server
+ which wants all surfaces to be client-side decorated will send Client,
+ a server which wants server-side decoration will send Server.
+
+ The client can request a different mode through the decoration request.
+ The server will acknowledge this by another event with the same mode. So
+ even if a server prefers server-side decoration it's possible to force a
+ client-side decoration.
+
+ The server may emit this event at any time. In this case the client can
+ again request a different mode. It's the responsibility of the server to
+ prevent a feedback loop.
+ </description>
+ <arg name="mode" type="uint" summary="The decoration mode applied to the surface by the server."/>
+ </event>
+ </interface>
+</protocol>
#ifdef GDK_WINDOWING_WAYLAND
if (GDK_IS_WAYLAND_DISPLAY (gtk_widget_get_display (GTK_WIDGET (window))))
- return TRUE;
+ {
+ GdkDisplay *gdk_display = gtk_widget_get_display (GTK_WIDGET (window));
+ return !gdk_wayland_display_prefers_ssd (gdk_display);
+ }
#endif
#ifdef GDK_WINDOWING_MIR
if (!priv->decorated || priv->client_decorated)
gdk_window_set_decorations (gdk_window, 0);
+#ifdef GDK_WINDOWING_WAYLAND
+ if (priv->client_decorated && GDK_IS_WAYLAND_WINDOW (gdk_window))
+ gdk_wayland_window_announce_csd (gdk_window);
+#endif
+
if (!priv->deletable)
gdk_window_set_functions (gdk_window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);